package com.hk.service.impl.kyc;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

import com.hk.commons.enm.MqEventType;
import com.hk.commons.entity.User;
import com.hk.commons.entity.UserCard;
import com.hk.commons.*;
import com.hk.commons.entity.product.ProductInfo;
import com.hk.commons.vo.*;
import com.hk.service.product.IProductInfo;
import org.hibernate.internal.util.StringHelper;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.hk.commons.ConstantCard;
import com.hk.commons.ConstantProduct;
import com.hk.commons.ConstantsCoupon;
import com.hk.commons.JsonUtils;
import com.hk.commons.RedisCilent;
import com.hk.commons.entity.Card;
import com.hk.commons.entity.Parameter;
import com.hk.service.kyc.ICoupon;
import com.hk.service.mq.IMq;
import com.hk.service.order.IParameter;

@Service
public class CouponImpl implements ICoupon {
	
	private Logger logger = LoggerFactory.getLogger(CouponImpl.class);
	
	private static String MQ_NAME = "activity_Req";
	
	
	@Value("${activity.baseUrl}")
	private String baseUrl;
	
	@Autowired
	private IMq mqService;
	
	@Autowired
	private IParameter parameterService;

	@Autowired
	private IProductInfo prodService;

	private RestTemplate template = new RestTemplate(); 
	
	@Override
	public UserCardMsg getCouponInfo(Long userId, Long userCardId) {
		UserCardMsg userCardMsg  = new UserCardMsg();
	
		try{
			
			
			String url = baseUrl + "api/couponWallet/" + userId + "/card/"+ userCardId;
			
			logger.info("getCouponInfo url = {}", url);
			 
			
			if (template.getForObject(url, String.class) != null) {
				
				String respStr  =  template.getForObject(url, String.class);
				
				logger.info("respStr = {}", respStr);
				
				JsonResult<UserCardMsg> respResult =  JsonUtils.toBean(respStr, JsonResult.class, UserCardMsg.class);
				
				userCardMsg = respResult.result;
				
			}else{
				userCardMsg = null;
				
				
			}
		}catch(Exception e){
			userCardMsg = null;
			logger.error(" getCouponInfo error msg ={}",e.getMessage());
		}
		
		return userCardMsg;
	}

	@Override
	public List<UserCardMsg> getCouponList(Long userId, int status){
		List<UserCardMsg> userCardList  = new ArrayList<UserCardMsg>();
	 
			String url = baseUrl + "api/couponWallet/" + userId+ "/status/"+ status;
			
			logger.info("getCouponList url = {}", url);
			
			if (template.getForObject(url, String.class) != null) {
				String respStr  =  template.getForObject(url, String.class);
				
				JSONObject json = new JSONObject(respStr);
				 
				try {
					userCardList = JsonUtils.toBean(json.get("result").toString(), List.class, UserCardMsg.class);
				} catch (JSONException | IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		return userCardList;
	}

	@Override
	public List<ProductUsableCardMsg> getProductUsableCardMsgList(Long productId) {
		return this.getProductUsableCouponList(productId);
	}

	@Override
	public List<UserCardMsg> getCouponList(Long userId){
		List<UserCardMsg> userCardList  = new ArrayList<UserCardMsg>();
	 
			String url = baseUrl + "api/couponWallet/" + userId;
			
			logger.info("getCouponList url = {}", url);
			
			if (template.getForObject(url, String.class) != null) {
				String respStr  =  template.getForObject(url, String.class);
				
				JSONObject json = new JSONObject(respStr);
				
				try {
					userCardList = JsonUtils.toBean(json.get("result").toString(), List.class, UserCardMsg.class);
				} catch (JSONException | IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		return userCardList;
	}
	

	@Override
	public CheckInfo sendCoupon(Long userId, Long cardId) {
		CouponInfo couponInfo = new CouponInfo();
		couponInfo.setCardId(cardId);
		couponInfo.setUserId(userId);
		
		MQmsg mqmsg = new MQmsg();
		mqmsg.setEvent(ConstantsCoupon.COUPON_ACTYPE_TAKED);
		mqmsg.setDesc("send userCard");
		String ssn = System.currentTimeMillis() + "_"+userId+ "_" + cardId + ConstantsCoupon.COUPON_ACTYPE_TAKED;
		
		mqmsg.setSsn(ssn);
		mqmsg.setMessage(couponInfo);
		
		mqService.setMessage(MQ_NAME, mqmsg);
		
		try {
			 logger.info("will start to send card -- sleep 5s stard ");
			 Thread.sleep(5000);
			 logger.info("will start to send card -- sleep 5s end ");
        
		} catch (InterruptedException e) {
        	
			e.printStackTrace(); 
        }
		
		return this.getActResult(mqmsg.getSsn().toString());
	}
	
	@Override
	public CheckInfo activeCoupon(Long userCardId, Long userId, Long orderId, Boolean status) {
		logger.info("will update  userCard  userCardId={}, userId={}, orderId={}, status={}", userCardId, userId, orderId, status);
		
		if(userCardId == null){
			CheckInfo checkInfo = new CheckInfo();
			checkInfo.setResult(true);
			
			return checkInfo;
		}
		
		
		
		CouponInfo couponInfo = new CouponInfo();
		couponInfo.setUserCardId(userCardId);
		couponInfo.setUserId(userId);
		
		if( orderId != null){
			couponInfo.setOrderId(orderId);
		}
		
		couponInfo.setStatus(status?"1":"0");
		
		MQmsg mqmsg = new MQmsg();
		
		mqmsg.setEvent(ConstantsCoupon.COUPON_ACTYPE_UPDATE);
		
		mqmsg.setDesc("active userCard");
		
		String ssn = System.currentTimeMillis() + "_" + userCardId+ "_" + ConstantsCoupon.COUPON_ACTYPE_UPDATE;
		
		mqmsg.setSsn(ssn);
		
		mqmsg.setMessage(couponInfo);
		
		mqService.setMessage(MQ_NAME, mqmsg);
		
		//默认激活成功
		CheckInfo checkInfo = new CheckInfo();
		checkInfo.setResult(true);
		
		return checkInfo;
		
		/*
		try {
			logger.info("will active userCard -- sleep 5s stard ");
		
			Thread.sleep(5000);
			
			logger.info("will active userCard -- sleep 5s end ");
        
		} catch (InterruptedException e) {
        	
			e.printStackTrace(); 
        }
		*/
		//return this.getActResult(mqmsg.getSsn().toString());
		
	}
	
	@Override
	public CheckInfo getActResult(String ssn ) {
		CheckInfo checkInfo = new CheckInfo();
		checkInfo.setResult(false);
		
		if (RedisCilent.existsKey(ssn)){
			
			String resultStr = RedisCilent.getString(ssn);
			
			if(StringHelper.isNotEmpty(resultStr) || resultStr.equals("1")){
				checkInfo.setResult(true);
			} 
			//result = JsonUtils.toBean(resultStr, Boolean.class);	
		}
		
		//logger.info("getActResult ssn ={}, status={}", ssn,  result);
		
		return checkInfo;
	}

	//2.7版本之前
	@Override
	public List<UserCardMsg> getCouponList(Long userId, int status, Long productId) {
		List<UserCardMsg> userCardList = this.getCouponList(userId, status);


		ProductInfo productInfo = prodService.findById(productId);
		if (productInfo == null || productInfo.getSaleType() == null) {
			return null;
		}
		if (status == 0) {
			List<ProductUsableCardMsg> productUsableCouponList = this.getProductUsableCouponList(productId);
			List<Long> unableCardIds = productUsableCouponList.stream()
					.map(p -> p.getCardid())
					.collect(Collectors.toList());
			userCardList = userCardList.stream()
					.filter(p -> unableCardIds.contains(p.getCardId()) && p.getCardType() != ConstantCard.CARD_TYPE_DJQ)
					.collect(Collectors.toList());
		}

		List<UserCardMsg> returnUserCardList = new ArrayList<>();


		BigDecimal rate01 = new BigDecimal(0.005).setScale(3, BigDecimal.ROUND_HALF_DOWN);
		BigDecimal rate02 = new BigDecimal(0.002).setScale(3, BigDecimal.ROUND_HALF_DOWN);


		for(UserCardMsg userCardMsg: userCardList){
			if(productInfo.getSaleType() == ConstantProduct.PRODUCT_TEST_PRODUCT && userCardMsg.getCardType() == ConstantCard.CARD_TYPE_TYJ){
				returnUserCardList.add(userCardMsg);
			}else if((productInfo.getSaleType() == ConstantProduct.PRODUCT_NO_TEST_PRODUCT || productInfo.getSaleType() == ConstantProduct.PRODUCT_SALETYPE_04)
					&&( userCardMsg.getCardType() == ConstantCard.CARD_TYPE_DJQ || userCardMsg.getCardType() == ConstantCard.CARD_TYPE_JXQ)) {

				if (productInfo.getIssuerId().intValue() == 3) {
					if (productInfo.getAddRateProduct01() != null) {
						ProductInfo rateProduct01 = this.prodService.findById(productInfo.getAddRateProduct01());
						if (rateProduct01 != null) {
							if (userCardMsg.getFaceValue().setScale(3, BigDecimal.ROUND_HALF_DOWN).equals(rate01)) {
								returnUserCardList.add(userCardMsg);
							}
						}
					}

					if (productInfo.getAddRateProduct02() != null) {
						ProductInfo rateProduct02 = this.prodService.findById(productInfo.getAddRateProduct02());
						if (rateProduct02 != null) {
							if (userCardMsg.getFaceValue().setScale(3, BigDecimal.ROUND_HALF_DOWN).equals(rate02)) {
								if (returnUserCardList.contains(userCardMsg) == false) {
									returnUserCardList.add(userCardMsg);
								}
							}

						}
					}
				} else {
					returnUserCardList.add(userCardMsg);
				}

			}
		}

		return returnUserCardList;
	}

	@Override
	public List<UserCardMsg> getCouponList(Long userId, int status,
										   Long productId, Long amount,int cardStatus) {
		List<UserCardMsg> userCardList  = this.getCouponList(  userId,   status);
		List<UserCardMsg> userCardListTemp = new ArrayList<>();

		ProductInfo productInfo = prodService.findById(productId);
		if(productInfo == null || productInfo.getSaleType() == null){
			return null;
		}

		if(status ==0){
			List<ProductUsableCardMsg> productUsableCouponList = this.getProductUsableCouponList(productId);
			/*过滤掉不是该产品适用的卡卷 2017-5-22 修改*/
			List<Long> unableCardIds = productUsableCouponList.stream()
					.map(p ->p.getCardid())
					.collect(Collectors.toList());

			userCardList = userCardList.stream()
					.filter(p -> unableCardIds.contains(p.getCardId()))
					.collect(Collectors.toList());


			for(UserCardMsg card:userCardList){
				boolean ungratified = productUsableCouponList.stream()
						.filter(p->p.getCardid().equals(card.getCardId()))
						.allMatch(p->amount < p.getConditionNum());
				if(card.getCardType() == ConstantCard.CARD_TYPE_DJQ){
					card.setDisplay(1);
				}
				if(cardStatus==0 && card.getCardType() == ConstantCard.CARD_TYPE_DJQ  && ungratified){ //选用贴息券并且购买金额比贴息券的起购金额少,不可用
					userCardListTemp.add(card);
				}else if(cardStatus ==1 && !ungratified){
					userCardListTemp.add(card);
				}
			}
			userCardList = userCardListTemp;
		}

		List<UserCardMsg> returnUserCardList = new ArrayList<>();


		BigDecimal rate01 = new BigDecimal(0.005).setScale(3, BigDecimal.ROUND_HALF_DOWN);
		BigDecimal rate02 = new BigDecimal(0.002).setScale(3, BigDecimal.ROUND_HALF_DOWN);


		for(UserCardMsg userCardMsg: userCardList){
			if(productInfo.getSaleType() == ConstantProduct.PRODUCT_TEST_PRODUCT && userCardMsg.getCardType() == ConstantCard.CARD_TYPE_TYJ){
				returnUserCardList.add(userCardMsg);
			}else if((productInfo.getSaleType() == ConstantProduct.PRODUCT_NO_TEST_PRODUCT || productInfo.getSaleType() == ConstantProduct.PRODUCT_SALETYPE_04)
					&&( userCardMsg.getCardType() == ConstantCard.CARD_TYPE_DJQ || userCardMsg.getCardType() == ConstantCard.CARD_TYPE_JXQ)) {

				if (productInfo.getBuyChannel() == ConstantBuyChannel.BUY_CHANNEL_HUOCHAI) {
					if (productInfo.getAddRateProduct01() != null) {
						ProductInfo rateProduct01 = this.prodService.findById(productInfo.getAddRateProduct01());
						if (rateProduct01 != null) {
							if (userCardMsg.getFaceValue().setScale(3, BigDecimal.ROUND_HALF_DOWN).equals(rate01)) {
								returnUserCardList.add(userCardMsg);
							}
						}
					}

					if (productInfo.getAddRateProduct02() != null) {
						ProductInfo rateProduct02 = this.prodService.findById(productInfo.getAddRateProduct02());
						if (rateProduct02 != null) {
							if (userCardMsg.getFaceValue().setScale(3, BigDecimal.ROUND_HALF_DOWN).equals(rate02)) {
								if (returnUserCardList.contains(userCardMsg) == false) {
									returnUserCardList.add(userCardMsg);
								}
							}

						}
					}
				} else {
					returnUserCardList.add(userCardMsg);
				}

			}
		}


		return returnUserCardList;
			
	}

	@Override
	public CheckInfo checkCoupon(UserCardMsg userCardMsg, int prodSaleType) {
		
		logger.info("checkCoupon userCardMsg = {}, prodSaleType={}", userCardMsg.toString(), prodSaleType);
		
		CheckInfo checkInfo = new CheckInfo();
		
		if(prodSaleType == ConstantProduct.PRODUCT_TEST_PRODUCT){
			if(userCardMsg.getCardType() == ConstantCard.CARD_TYPE_TYJ){
				checkInfo.setResult(true);
				checkInfo.setResultMsg("成功");
			}else{
				checkInfo.setResult(false);
				checkInfo.setResultMsg("该产品仅支持使用体验金");
			}
			
		}
		
		if(prodSaleType == ConstantProduct.PRODUCT_NO_TEST_PRODUCT){
			if(userCardMsg.getCardType() == ConstantCard.CARD_TYPE_DJQ || userCardMsg.getCardType() == ConstantCard.CARD_TYPE_JXQ){
				checkInfo.setResult(true);
				checkInfo.setResultMsg("成功");
			}else{
				checkInfo.setResult(false);
				checkInfo.setResultMsg("该产品仅支持使用代金券或加息券");
				
			}
		}
		
		logger.info("checkCoupon  userCardId= {}, checkReslut={}",  userCardMsg.getUserCardId(), checkInfo.toString());
		
		return checkInfo;
	}
	
	 
	 
	
	@Override
	public CheckInfo sendJXQToUser(Long userId) {
		logger.info("给用户赠送加息券  userId={}", userId);
		CheckInfo checkInfo = new CheckInfo();
		
		Parameter parmCard = null;

		LocalDate now = LocalDate.now();
		LocalDate newYear = LocalDate.of(2017, 1, 1);

		if (now.compareTo(newYear) == 0) {
			parmCard = parameterService.getByName(ConstantCard.SEND_CARD_NEW_YEAR_ID);
		} else {
			parmCard = parameterService.getByName(ConstantCard.SEND_CARD_ID);
		}


		if (parmCard == null || StringHelper.isEmpty(parmCard.getValue01())) {
			logger.info("在参数表中找不到对应的参数， 或参数值为空");
			checkInfo.setResult(false);
			checkInfo.setResultMsg("在参数表中找不到对应的参数， 或参数值为空");
			return checkInfo;
		}

		// 发送加息券
		Long userCardId = Long.valueOf(parmCard.getValue01());

		logger.info("贈送加息券 userCardId = {}", userCardId );

		if(userCardId != null){
			checkInfo = this.sendCoupon(userId, userCardId);
		}else{
			checkInfo.setResult(false);
			checkInfo.setResultMsg("贈送加息券失敗！");
			logger.error("贈送加息券失敗");
		}
		return checkInfo;
	}



	@Override
	public CheckInfo sendTYJToUser(Long userId) {
		logger.error("给用户赠送体验金  userId={}", userId);
		
		CheckInfo checkInfo = new CheckInfo();
		
		Parameter parmCard = parmCard = parameterService.getByName(ConstantCard.SEND_CARD_TYJ_ID);
		
		if (parmCard == null || StringHelper.isEmpty(parmCard.getValue01())) {
			logger.error("在参数表中找不到参数 SEND_CARD_TYJ_ID， 或参数值为空");
			checkInfo.setResult(false);
			checkInfo.setResultMsg("在参数表中找不到参数 SEND_CARD_TYJ_ID， 或参数值为空");
			logger.error("在参数表中找不到参数 SEND_CARD_TYJ_ID， 或参数值为空");
			return checkInfo;
		}

		// 发送加息券
		Long userCardId = Long.valueOf(parmCard.getValue01());
		
		if(userCardId != null){
			checkInfo = this.sendCoupon(userId, userCardId);
		}else{
			checkInfo.setResult(false);
			checkInfo.setResultMsg("贈送体验金失敗！");
			logger.error("贈送体验金失敗");
		}
		return checkInfo;
	}

	@Override
	public CheckInfo sendJTLSKToUser(Long userId) {
		
		logger.error("给用户赠送家庭律师卡  userId={}", userId);
		
		CheckInfo checkInfo = new CheckInfo();
		
		Parameter parmCard = parameterService.getByName(ConstantCard.SEND_CARD_JTLSK_ID);
		
		if (parmCard == null || StringHelper.isEmpty(parmCard.getValue01())) {
			logger.error("在参数表中找不到参数 SEND_CARD_JTLSK_ID， 或参数值为空");
			checkInfo.setResult(false);
			checkInfo.setResultMsg("在参数表中找不到参数 SEND_CARD_JTLSK_ID， 或参数值为空");
			logger.error("在参数表中找不到参数 SEND_CARD_JTLSK_ID， 或参数值为空");
			return checkInfo;
		}

		// 发送加息券
		Long userCardId = Long.valueOf(parmCard.getValue01());
		
		if(userCardId != null){
			checkInfo = this.sendCoupon(userId, userCardId);
		}else{
			checkInfo.setResult(false);
			checkInfo.setResultMsg("贈送家庭律师卡失敗！");
			logger.error("贈送家庭律师卡失敗");
		}
		return checkInfo;
	}

	/**
	 * 根据产品ID，获取可用优惠券列表
	 * @param productId
	 * @return
	 */
	private List<ProductUsableCardMsg> getProductUsableCouponList(Long productId){
		List<ProductUsableCardMsg> usableCardList  = new ArrayList<ProductUsableCardMsg>();
		String url = baseUrl +"api/coupon/productCanUse/list/"+productId;
		logger.info("getProductUsableCouponList url={}",url);
		String respStr = template.getForObject(url,String.class);
		if(respStr != null){
			JSONObject json = new JSONObject(respStr);
			try {
				usableCardList = JsonUtils.toBean(json.get("result").toString(),List.class,ProductUsableCardMsg.class);
			} catch (JSONException | IOException e) {
				e.printStackTrace();
			}
		}
		return usableCardList;
	}

	@Override
	public Integer countByActivityType(Long userId, String cardType) {
		String url = baseUrl +"api/wallet/countByActivityType?userId="+userId+ "&type="+ cardType;
		logger.info("countByActivityType url={}",url);

		Integer size = -1;
		String respStr = template.getForObject(url,String.class);
		logger.info("response ={}", respStr);
		if(respStr != null){
			JSONObject json = new JSONObject(respStr);
			try {
				String sizeStr = json.get("result").toString();
				logger.info("sizeStr ={}", sizeStr);
				if(StringHelper.isNotEmpty(sizeStr)){
					size = Integer.valueOf(sizeStr);
				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("countByActivityType error e={}", e);
			}
		}
		return size;
	}
}
